# vim: filetype=sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.

. $STF_SUITE/include/libtest.kshlib

function cleanup
{
	poolexists $TESTPOOL && log_must $ZPOOL status $TESTPOOL
	poolexists $TESTPOOL2 && log_must $ZPOOL status $TESTPOOL2
	destroy_pool $TESTPOOL
	destroy_pool $TESTPOOL2
}

#
# Try zpool status/iostat for given pool
#
# $1 pool
#
function display_status
{
	typeset pool=$1

	typeset -i ret=0
	$ZPOOL status -xv $pool > /dev/null 2>&1
	ret=$?

	$ZPOOL iostat > /dev/null 2>&1
	((ret |= $?))

	typeset mntpnt=$(get_prop mountpoint $pool)
	$DD if=/dev/random of=$mntpnt/testfile.${TESTCASE_ID} &
	typeset pid=$!

	$ZPOOL iostat -v 1 3 > /dev/null
	((ret |= $?))

	kill -9 $pid

	return $ret
}

function slog_devstat_table
{
	typeset pool=$1

	$ZPOOL status -v $pool | $NAWK '
		BEGIN { start = 0; }
		/\tlogs/ { start = 1; }
		(start == 0) { next; }
		/\t  (\/|[a-zA-Z])/ { print "stripe:" $1 " " $2; }
		/\t    (\/|[a-zA-Z])/ { print "mirror:" $1 " " $2; }
		/\t  (\/|[0-9])/ {print "stripe:" $NF " " $2}
		/\t    (\/|[0-9])/ {print "mirror:" $NF " " $2}
		# When a hotspare is replacing
		/\t      (\/|[a-zA-Z])/ {print "mirror:" $1 " " $2}
	'
}

#
# Verify the given slog device have correct type and status
#
# $1 pool name
# $2 device name
# $3 device status
# $4 device type
#
function verify_slog_device
{
	typeset pool=$1
	typeset device=$2
	typeset status=$3
	typeset type=$4

	if [[ -z $pool || -z $device || -z $status ]]; then
		log_fail "Usage: verify_slog_device <pool> <device> " \
			"<status> [type]"
	fi

	if [[ $WRAPPER == *"smi"* ]]; then
		$ECHO $device | $EGREP "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
		if (( $? == 0 )); then
			device=${device}s2
		fi
	fi

	#
	# Get all the slog devices and status table like below
	#
	# mirror:/disks/d ONLINE mirror:/disks/e ONLINE stripe:/disks/f ONLINE
	#
	set -A dev_stat_tab $(slog_devstat_table $pool)

	typeset find=0
	for (( i = 0; i < ${#dev_stat_tab[@]}; i += 2 )); do
		typeset dev=${dev_stat_tab[$i]}
		typeset stat=${dev_stat_tab[((i+1))]}

		typeset statmsg="$dev: Status($stat) != Expected stat($status)"
		case $dev in
			stripe:$device)	
				if [[ "$type" == 'mirror' ]]; then
					log_note "Unexpected type: mirror"
					return 1
				fi
				if [[ $stat != $status ]]; then
					log_note statmsg
					return 1
				fi
				return 0
				;;
			mirror:$device)
				if [[ -z "$type" || $type == 'stripe' ]]; then
					log_note "Unexpected type: stripe"
					return 1
				fi
				if [[ $stat != $status ]]; then
					log_note statmsg
					return 1
				fi
				return 0
				;;
		esac
	done
	return 1
}

# Calls <callback> [args...] <pooltype> <sparetype>.
function slog_foreach_nologtype # <callback>
{
	typeset callback="$1"

	for pooltype in "" "mirror" "raidz" "raidz2"; do
		for sparetype in "" "spare"; do
			$callback "$pooltype" "$sparetype"
		done
	done
}

# Calls <callback> [args...] <pooltype> <sparetype> <logtype>.
# Unfortunately, this has to be duplicated because some arguments are empty,
# so if they aren't explicitly forwarded they aren't arguments to $callback.
function slog_foreach_all # <callback>
{
	typeset callback="$1"

	for pooltype in "" "mirror" "raidz" "raidz2"; do
		for sparetype in "" "spare"; do
			for logtype in "" "mirror"; do
				$callback "$pooltype" "$sparetype" "$logtype"
			done
		done
	done
}
